/*
 * @Author: CB
 * @Date: 2023-08-01 10:46:11
 * @Description: 微信广告管理器
 */
import { Size, view } from "cc";
import { PluginAds } from "../PluginAds";
import { oops } from "db://oops-framework/core/Oops";

/** 小游戏banner最小宽度 */
const bannerMinWidth = 300;
/** banner 1004 错误后重新创建间隔时间  ms*/
const bannerErrInterval = 3000;

export class PluginAdsWechat extends PluginAds {
    private viewSize: Size;
    constructor() {
        super();
        this.viewSize = view.getVisibleSize();
    }

    //#region banner 相关 ==================================================
    /** banner 1004 错误后重新创建计时器 */
    private bannerErrTimer: number | NodeJS.Timeout;
    /** 当前显示的banner */
    private nowBanner: any;

    /** 是否正在创建banner */
    private isCreatingBanner: boolean = false;

    /** 是否需要显示banner */
    private needShowBanner: boolean = false;

    /** 显示banner广告 */
    showBannerAD(bannerId?: string, height?: number) {
        this.needShowBanner = true;
        if (!height) return;
        if (this.isCreatingBanner) {
            oops.log.trace(`AdsManager showBanner 正在创建banner，请稍后再试`);
            return;
        }
        try {
            const whRatio = this.viewSize.width / this.viewSize.height;
            const bannerWidth = height * whRatio;
            if (bannerWidth < bannerMinWidth) {
                oops.log.trace(`AdsManager showBanner banner宽度小于最小宽度 ${bannerWidth} ${bannerMinWidth}`);
                return;
            }
            this.isCreatingBanner = true;
            //@ts-ignore
            const banner = wx.createBannerAd({
                adUnitId: "adunit-" + bannerId,
                style: {
                    left: 0,
                    top: this.viewSize.height - height,
                    width: bannerWidth,
                    height: height
                }
            });
            if (banner) {
                banner.onLoad(() => {
                    oops.log.trace(`AdsManager showBanner banner广告加载成功`);
                    if (this.bannerErrTimer) {
                        clearTimeout(this.bannerErrTimer);
                        this.bannerErrTimer = null;
                    }
                });
                banner.onError((err) => {
                    oops.log.trace(`AdsManager showBanner banner广告加载失败 ${err}`);
                    if (err?.errCode === 1004 && !this.bannerErrTimer) {
                        this.bannerErrTimer = setTimeout(() => {
                            this.showBannerAD(bannerId, height);
                        }, bannerErrInterval);
                    }
                });
                banner.onResize((size) => {
                    oops.log.trace(`AdsManager showBanner banner广告尺寸变化 ${size}`);
                });
                banner.show().then(() => {
                    this.isCreatingBanner = false;
                    this.nowBanner = banner;
                    if (!this.needShowBanner) this.nowBanner.hide();
                }).catch(() => {
                    if (banner) {
                        banner.hide();
                        banner.destroy();
                    }
                    if (this.needShowBanner && this.nowBanner) {
                        this.nowBanner.show();
                    }
                    this.isCreatingBanner = false;
                })
            } else {
                this.isCreatingBanner = false;
            }
        } catch (error) {
            oops.log.trace(`AdsManager showBanner ${error}`);
            this.isCreatingBanner = false;
        }
    }

    hideBannerAD(): void {
        this.needShowBanner = false;
        if (this.nowBanner) {
            this.nowBanner.hide();
        }
    }
    //#endregion

    //#region 插屏广告 ==================================================
    /** 插屏广告 */
    private interstitialAD: any;

    /** 插屏广告状态 0：初始状态（未加载广告） 1：加载中  2：已加载  3：正在显示*/
    private interstitialADStatus: number = 0;

    private callbackInterstitialAD: (success: boolean) => void;

    /** 创建插屏广告 */
    createInterstitialAD(adId: string): void {
        if (this.interstitialADStatus !== 0) return;
        this.interstitialADStatus = 1;
        //@ts-ignore
        this.interstitialAD = wx.createInterstitialAd({
            adUnitId: 'adunit-' + adId
        });
        if (this.interstitialAD) {
            this.interstitialAD.offLoad();
            this.interstitialAD.offError();
            this.interstitialAD.offClose();
            this.interstitialAD.onLoad(this._onInterstitialADLoad);
            this.interstitialAD.onError(this._onInterstitialADError);
            this.interstitialAD.onClose(this._onInterstitialADClose);
        }
    }

    showInterstitialAd(callback?: (success: boolean) => void): void {
        this.callbackInterstitialAD = callback;
        if (this.interstitialADStatus !== 2 || !this.interstitialAD) {
            this.callbackInterstitialAD(false);
            this.callbackInterstitialAD = null;
            return;
        }
        this.interstitialADStatus = 3;
        this.interstitialAD.show().then(() => {
            this.interstitialADStatus = 0;
            if (this.callbackInterstitialAD) {
                this.callbackInterstitialAD(true);
                this.callbackInterstitialAD = null;
            }
        }).catch((err) => {
            this.interstitialADStatus = 0;
            oops.log.trace(`AdsManager showInterstitialAd 插屏广告显示失败 ${err}`);
            if (this.callbackInterstitialAD) {
                this.callbackInterstitialAD(false);
                this.callbackInterstitialAD = null;
            }
        });
    }


    private _onInterstitialADLoad() {
        this.interstitialADStatus = 2;
    }

    private _onInterstitialADError(err) {
        this.interstitialADStatus = 0;
        if (this.callbackInterstitialAD) {
            this.callbackInterstitialAD(false);
            this.callbackInterstitialAD = null;
        }
    }

    private _onInterstitialADClose() {
        this.interstitialADStatus = 0;
        if (this.callbackInterstitialAD) {
            this.callbackInterstitialAD(true);
            this.callbackInterstitialAD = null;
        }
    }


    //#endregion


    //#region 激励视频 ==================================================
    /** 显示激励视频广告 */
    showRewardAD(finishCallback?: (success: boolean) => void, errorCallback?: (error: string) => void) {
        oops.gui.toast('showRewardAD');
        finishCallback && finishCallback(true);
    }

    //#endregion
}